
package comandaXM.utils;



import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.classic.Session;
import comandaXM.excepcions.ExceptionHibernate;
import org.hibernate.cfg.Configuration;


/**
 * Classe que representa a les utilitats imprescindibles per a portar a terme les transaccions a la base de dades<br>
 * També utititats per realitzar tasques comunes d'inserció, modificació i eliminació.
 * @author Xavier Martí Moret 
 *
 */
public class HibernateUtil {

	private static final SessionFactory sessionFactory = buildSessionFactory();
	/**
	 * Crea una sessió per hibernate a partir dels paràmetres del fitxer de configuració
	 * @return
	 */
	private static SessionFactory buildSessionFactory() {
		try {
			// Create the SessionFactory from hibernate.cfg.xml
			//return new AnnotationConfiguration().configure()
			//		.buildSessionFactory();

                     return new Configuration().configure().buildSessionFactory();  

                } catch (Throwable ex) {
			System.err.println("Initial SessionFactory creation failed." + ex);
			throw new ExceptionInInitializerError(ex);
		}
	}
	/**
	 * Obté una sessió 
	 * @return SessionFactory
	 */
	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	/**
	 * Insereix un objecte a la base de dades
	 * @param object Objecte a inserir
	 * @return CERT si es realitza l'operació, FALS en cas contrari
         * @throws xmarti..exception.ExceptionHibernate
	 */
	public boolean add(Object object) throws ExceptionHibernate {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
                boolean state=false;                
		try{			                        
                        session.save(object);                                                
			session.getTransaction().commit();
                        state=true; 
		}catch (Exception e){			
			session.getTransaction().rollback();
			state=false;
                       throw new ExceptionHibernate(ExceptionHibernate.getMessage(e.getMessage()));                    
		}
		
		return state;
	}
        
	/**
         * 
         * @param object
         * @return
         * @throws ExceptionHibernate 
         */
	public boolean delete(Object object) throws ExceptionHibernate{
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		boolean result=false;
                try{
                    session.delete(object);                    
                    session.getTransaction().commit();
                    result=true; 
                }catch(HibernateException he){
                    session.getTransaction().rollback();
                   throw new ExceptionHibernate(ExceptionHibernate.getMessage(he.getMessage()));
                }
                return result;
	}
	/**
	 * Modifica un objecte de la base de dades
	 * @param object Objecte a modificar
	 * @return CERT si es realtiza l'operació, FALS en cas contrari
         @ throws ExceptionHibernate 
	 */
	public boolean  update(Object object) throws ExceptionHibernate{
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
		try{
			session.merge(object);
			session.getTransaction().commit();
		}catch (Exception e){
                        session.getTransaction().rollback();                                                       
                        throw new ExceptionHibernate(ExceptionHibernate.getMessage(e.getCause().getMessage()));
                        
		}
		return true;
	}
        /**
         * 
         * @param object1
         * @param object2
         * @return
         * @throws ExceptionHibernate 
         */
        public boolean update(Object object1, Object object2) throws ExceptionHibernate {
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
                boolean state=false;
		try{			                        
                        session.merge(object1);
                        session.merge(object2);
			session.getTransaction().commit();
                        state=true; 
		}catch (Exception e){			
			session.getTransaction().rollback();
			state=false;
                        throw new ExceptionHibernate(ExceptionHibernate.getMessage(e.getMessage()));
		}
		
		return state;
	}
        /**
         * 
         * @param <T>
         * @param id
         * @param entityClass
         * @return
         * @throws ExceptionHibernate 
         */
        public  <T> T getObjectById(Serializable id, Class<T> entityClass) throws ExceptionHibernate {        
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            T recoveredObject = null;
            try
            {                
                recoveredObject = (T)session.get(entityClass, id);              
            }
            catch (HibernateException he)
            {                
                throw new ExceptionHibernate(ExceptionHibernate.getMessage(he.getMessage()));						
            }
            
            return recoveredObject;
        }
        /**
         * 
         * @param <T>
         * @param entityClass
         * @return
         * @throws ExceptionHibernate 
         */
        public  <T> List<T> getList(Class<T> entityClass) throws ExceptionHibernate {        
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            List<T> resultList = new ArrayList<T>();
            try
            {            
                resultList= session.createQuery("FROM " + entityClass.getSimpleName()).list();
            }
            catch (HibernateException he)
            {
               throw new ExceptionHibernate(ExceptionHibernate.getMessage(he.getMessage()));
            }
            return resultList;
        }
        /**
         * 
         * @param <T>
         * @param entityClass
         * @return
         * @throws ExceptionHibernate 
         */
         public  <T> List<T> getListActive(Class<T> entityClass) throws ExceptionHibernate {        
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            List<T> resultList = null;
            try
            {            
                resultList= session.createQuery("FROM " + entityClass.getSimpleName()+ " e where e.active=true").list();
            }
            catch (HibernateException he)
            {
                throw new ExceptionHibernate(ExceptionHibernate.getMessage(he.getMessage()));
            }
            return resultList;
        }
         
}
